#include "ComponentMovable.h"

#include "../constant.h"

#include "../util.h"

#include "ComponentRenderable.h"

ComponentMovable::ComponentMovable(ComponentManager* _parent, ComponentArguments _args):
    Component(_parent, _args)
{
    //ctor



    addProperty<float>("max_speed", _args.getArgument<float>("max_speed"));
    addProperty<float>("acceleration", _args.getArgument<float>("acceleration"));

    m_speed=0.0;

    m_isAtTarget=true;


    m_target=Ogre::Vector3(0,0,0);
    m_direction=Ogre::Vector3(0,0,0);


    m_positionComponent=0;
    if (m_parent->hasComponent("Position"))
    {
        m_positionComponent = ((ComponentPosition*)m_parent->getComponent("Position"));

        m_target = m_positionComponent->getPosition();

        update(FIRST_STEP_TIME);

    }
}

ComponentMovable::~ComponentMovable()
{
    //dtor
}



/** @brief registerNewComponent
  *
  * @todo: document this function
  */
void ComponentMovable::registerNewComponent(std::string _newComponentName)
{

}

/** @brief update
  *
  * @todo: document this function
  */
void ComponentMovable::update(double timeSinceLastFrame)
{



    if (!m_isAtTarget)
    {
        walk(timeSinceLastFrame);
    }
    else
    {
        if (m_waypoints.size()>0)
        {
            goToOrder(m_waypoints.front());
            m_waypoints.pop_front();

        }
    }
}


/** @brief walk
  *
  * @todo: document this function
  */
void ComponentMovable::walk(double timeSinceLastFrame)
{
    //OgreFramework::getSingletonPtr()->m_pLog->logMessage("ComponentMovable::walk()");


    if (getDistanceFromWalkTarget()<0.05)
    {


        m_isAtTarget=true;
    }
    else
    {

        ((ComponentRenderable*)m_parent->getComponent("Renderable"))->facePoint(m_target);

        m_isAtTarget=false;

        Ogre::Vector3 direction = m_target - m_positionComponent->getPosition();
        direction.normalise();



        Ogre::Vector3 off = getPropertyValue<float>("max_speed")*direction * timeSinceLastFrame;

        m_positionComponent->setPosition(m_positionComponent->getPosition()+off);
    }

}






/** @brief loadFromXML
  *
  * @todo: document this function
  */
void ComponentMovable::loadFromXML(TiXmlElement* parentElement)
{

}

/** @brief saveToXML
  *
  * @todo: document this function
  */
void ComponentMovable::saveToXML(TiXmlElement* parentElement)
{
    TiXmlElement* element = new TiXmlElement("movable");
    parentElement->LinkEndChild(element);

    element->SetDoubleAttribute("max_speed", getPropertyValue<float>("max_speed"));

}

/** @brief destroy
  *
  * @todo: document this function
  */
void ComponentMovable::destroy()
{

}

/** @brief initialise
  *
  * @todo: document this function
  */
void ComponentMovable::initialize()
{

}




/** @brief goTo
  *
  * @todo: document this function
  */
void ComponentMovable::goToOrder(Ogre::Vector3 _position)
{

    m_target = _position;
    if (getDistanceFromWalkTarget()>0.01)
    {
        m_isAtTarget=false;
    }

}
void ComponentMovable::goToOrder(Ogre::Vector2 _position)
{

    m_target = addYtoVector2(_position,0);
    goToOrder(m_target);

}

/** @brief getDistanceFromWalkTarget
  *
  * @todo: document this function
  */
float ComponentMovable::getDistanceFromWalkTarget()
{
    return m_positionComponent->getPosition().distance(m_target);
}

/** @brief clearWayPoints
  *
  * @todo: document this function
  */
void ComponentMovable::clearWayPoints()
{
    m_waypoints.clear();
}

/** @brief addWayPoints
  *
  * @todo: document this function
  */
void ComponentMovable::addWayPoints(std::list<Ogre::Vector2> list)
{

    m_waypoints.merge(list);
}

void ComponentMovable::addWayPointsAfterClear(std::list<Ogre::Vector2> list)
{
    m_waypoints.clear();
    m_isAtTarget=true;
    m_waypoints.merge(list);
}



